/*
 * Copyright 2009 Rohan Ranade
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.fcr;

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.text.AttributedString;

/**
 * Renders a card
 * 
 * @author Rohan Ranade
 */
public class CardRenderer {

    public static final String PNG_FORMAT = "png";

    private CardRenderConfig renderConfig;

    public CardRenderer() {
    }

    public CardRenderConfig getRenderConfig() {
        return renderConfig;
    }

    public void setRenderConfig(CardRenderConfig renderConfig) {
        assert renderConfig != null;
        this.renderConfig = renderConfig;
    }

    public BufferedImage renderCard(Card card) {
        if (renderConfig == null) {
            throw new IllegalStateException("Cannot render a card without a rendering configuration");
        }
        int width = renderConfig.getWidth();
        int height = renderConfig.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g = image.createGraphics();
        g.setColor(renderConfig.getBackgroundColor());
        g.fillRect(0, 0, width, height);
        renderTextSection(g, card.getName(), 10, 10, 300, 35, renderConfig.getNameFont());
        renderTextSection(g, card.getHint(), 10, 50, 300, 35, renderConfig.getHintFont());
        renderBlockTextSection(g, card.getDescription(), 10, 90, 300, 140, renderConfig.getDescriptionFont());
        return image;
    }

    private void renderTextSection(Graphics2D g, String text, int x, int y, int width, int height, Font font) {
        Font orig = g.getFont();
        g.setFont(font);
        g.setColor(renderConfig.getSectionBackgroundColor());
        g.fillRect(x, y, width, height);
        g.setColor(renderConfig.getSectionBorderColor());
        g.drawRect(x, y, width, height);
        AttributedString as = new AttributedString(text);
        as.addAttribute(TextAttribute.FONT, font);
        FontMetrics fontMetrics = g.getFontMetrics();
        int fontHeight = fontMetrics.getHeight();
        assert fontHeight < height;
        int fontBaseY = y + fontHeight;
        g.drawString(as.getIterator(), x + 5, fontBaseY);
        g.setFont(orig);
    }

    private void renderBlockTextSection(Graphics2D g, String text, int x, int y, int width, int height, Font font) {
        Font orig = g.getFont();
        g.setFont(font);
        g.setColor(renderConfig.getSectionBackgroundColor());
        g.fillRect(x, y, width, height);
        g.setColor(renderConfig.getSectionBorderColor());
        g.drawRect(x, y, width, height);
        FontRenderContext frc = g.getFontRenderContext();
        AttributedString as = new AttributedString(text);
        as.addAttribute(TextAttribute.FONT, font);
        LineBreakMeasurer lbm = new LineBreakMeasurer(as.getIterator(), frc);
        FontMetrics fontMetrics = g.getFontMetrics();
        TextLayout tl;
        int rowHeight = fontMetrics.getHeight();
        int startY = rowHeight + y;
        while ((tl = lbm.nextLayout(width - 10)) != null) {
            tl.draw(g, x + 5, startY);
            startY+= rowHeight;
        }
        g.setFont(orig);
    }
}
